package org.icy.core.installation;

import java.io.File;

import org.ice.config.ConfigData;
import org.icy.core.parser.XMLParser;
import org.icy.utils.FileUtils;
import org.icy.utils.PathUtils;

public class InstallWorker {

	private File module;
	private File extracted;
	private File description;
	private String mod;
	private boolean copied;

	public void install(File module) throws Exception {
		this.module = module;
		this.copied = false;
		// extract
		extracted = extractModule();
		// parse description file
		description = new File(extracted, "module.xml");
		try {
			ConfigData cfg = new XMLParser().parse(description);
			processConfig(cfg);
		} catch (Exception ex) {
			try {
				if (copied) {
					File f = new File(getModulesDirectory() + File.separator
							+ "mod_" + mod.toLowerCase());
					uninstall(f, description);
				}
			} catch (Exception e) {

			}
			throw ex;
		}
	}

	public void uninstall(File module, File description) throws Exception {
		if (description == null)
			description = new File(module, "module.xml");
		if (description.exists()) {
			ConfigData cfg = new XMLParser().parse(description);
			processUninstallConfig(module, cfg);
		}
		
		if (module != null && module.exists()) {
			FileUtils.deleteFolder(module);
		}
	}

	private void processUninstallConfig(File module, ConfigData cfg)
			throws Exception {
		String uninstallFile = cfg.get("uninstall-file");
		if (uninstallFile != null && !uninstallFile.isEmpty()) {
			InstallModel model = new InstallModel();
			File sqlFile = new File(module, uninstallFile);
			try {
				String sql = FileUtils.readFile(sqlFile);
				model.runQuery(sql);
				if (model.getLastError() != null)
					throw model.getLastError();
			} catch (Exception ex) {
				throw new Exception("Error while uninstalling sql file ["
						+ sqlFile.getAbsolutePath() + "]: " + ex.toString());
			}
		}
	}

	private void processConfig(ConfigData cfg) throws Exception {
		mod = cfg.get("name");
		File installFolder = new File(extracted, "mod_" + mod.toLowerCase());
		File dst = null;
		if (installFolder.isDirectory()) {
			dst = getModulesDirectory();
			if (!dst.exists() || !dst.canWrite())
				throw new Exception(
						"Error while copying module files. Permission denied: "
								+ dst.getAbsolutePath());
			try {
				dst = new File(dst, "mod_"+mod.toLowerCase());
				if (dst.exists())
					throw new Exception("Directory exist: "+dst.getAbsolutePath());
				boolean b = dst.mkdir();
				if (!b)
					throw new Exception("Cannot create directory: "+dst.getAbsolutePath());
				FileUtils.copy(installFolder, dst);
				FileUtils.copy(description, dst);
				copied = true;
			} catch (Exception ex) {
				throw new Exception("Error while copying module files: "
						+ ex.toString());
			} finally {
				FileUtils.deleteFolder(extracted);
			}
		}

		String installFile = cfg.get("install-file");
		if (installFile != null && !installFile.isEmpty()) {
			InstallModel model = new InstallModel();
			File sqlFile = new File(dst, installFile.trim());
			try {
				if (!sqlFile.exists()) {
					throw new Exception("File not exist");
				}
				String sql = FileUtils.readFile(sqlFile);
				model.runQuery(sql);
				if (model.getLastError() != null)
					throw model.getLastError();
			} catch (Exception ex) {
				throw new Exception("Error while installing sql file ["
						+ sqlFile.getAbsolutePath() + "]: " + ex.toString());
			}
		}
	}

	private File getModulesDirectory() {
		return new File(PathUtils.getAbsolutePath("/resource/modules/"));
	}

	private File extractModule() throws Exception {
		File baseFolder = new File(
				PathUtils.getAbsolutePath("/resource/upload"));
		return new File(FileUtils.unzip(module, baseFolder));
	}
}
